package qc.module.demo.api.controller;

import com.rtdb.api.model.RtdbData;
import com.rtdb.enums.RtdbHisMode;
import com.rtdb.model.SummaryEntity;
import com.rtdb.service.impl.HistorianImpl;
import com.rtdb.service.impl.ServerImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import qc.common.core.pair.GenericKeyValuePairDto;
import qc.common.core.utils.DateUtil;
import qc.common.core.utils.TimeSpanUtil;
import qc.module.demo.dto.powerplant.*;
import qc.module.demo.service.TsNumDataService;

import java.util.*;
import java.util.stream.Collectors;

import static java.lang.Double.NaN;

/**
 * LED显示控制器
 * @author QuCheng Tech
 * @since 2023/12/20
 */
@RestController
@RequestMapping("/leddisplay")
public class LedDisplayController {

    @Autowired
    private TsNumDataService tsNumDataService;

    /**
     * 获取电厂实时数据，可以指定传入日期
     * @param id 传入日期，为空时使用当天
     * @return qc.module.cms.dto.leddisplay.PlantRealDataDto
     * @author QuCheng Tech
     */
    @RequestMapping(value = "/yzh", method = {RequestMethod.GET})
    public PlantRealDataDto getDynamoRealDatasByParam(@RequestParam(value = "id", required = false) String id) throws Exception {
        return getDynamoRealDatas(id);
    }

    /**
     * 获取电厂实时数据，可以指定传入日期
     *
     * @param id 传入日期，为空时使用当天
     * @return qc.module.cms.dto.leddisplay.PlantRealDataDto
     * @author QuCheng Tech
     */
    @RequestMapping(value = "/yzh/{id}", method = {RequestMethod.GET})
    public PlantRealDataDto getDynamoRealDatasByPath(@PathVariable(required = false) String id) throws Exception {
        return getDynamoRealDatas(id);
    }

    /**
     * 从阳宗海电厂SIS中获取数据测试
     *
     * @return java.lang.Object
     * @author QuCheng Tech
     * @since 2025/10/9
     */
    @RequestMapping(value = "/yzhsistest", method = {RequestMethod.GET})
    public Map<String, String> getDataFromSisTest() {
        Map<String, String> result = new LinkedHashMap<>();

        Date date = DateUtil.getNowDate();
        //查询时间段（当日初始时间）
        Date today = DateUtil.getDayDate(date);
        Date yearBeginTime = DateUtil.newDate(DateUtil.getYear(date), 0, 1);
        Date monthBeginTime = DateUtil.newDate(DateUtil.getYear(date), DateUtil.getMonth(date, false), 1);

        try {
            //获取单个数据库连接
            ServerImpl server = new ServerImpl("10.113.96.14", 6327, "sa", "VeStore-123#!");
            //历史查询服务实现类
            HistorianImpl historian = new HistorianImpl(server);
            //定义阳宗海SIS中的点号
            //负荷点号
            final int dynamo1MwId = 63479;//3#机组负荷
            final int dynamo2MwId = 66030;//4#机组负荷
            //电量点号
            final int dynamo1EngcId = 76709;//3#机组电量 DL7.DLAI7017
            final int dynamo2EngcId = 76713;//4#机组电量 DL7.DLAI7021
            //环保点号
            final int dynamo1So2Id = 63489;//3# SO2 CHHYQLND.TL3
            final int dynamo1NoxId = 63490;//3# NOx CHHYQNND.TL3
            final int dynamo1SmokeId = 63491;//3# 烟尘 CHHYQYCN.TL3
            final int dynamo2So2Id = 66027;//4# SO2 DHHYQLND.TL4
            final int dynamo2NoxId = 66029;//4# NOx DHHYQNND.TL4
            final int dynamo2SmokeId = 66018;//4# 烟尘 DHHYQYCN.TL4

            //2025-10-9，由于阳宗海其中1台机组更换电量表导致电量累计读数重新计数，直接相减得到的年电量为负值
            SummaryEntity yearSummaryEntity1 = historian.getNumberSummary(dynamo1EngcId, yearBeginTime, today);

            result.put("3#机组年电量 累计值", String.valueOf(yearSummaryEntity1.getTotalValue()));
            result.put("3#机组年电量 最小值", String.valueOf(yearSummaryEntity1.getMinValue()));
            result.put("3#机组年电量 最小值时间", DateUtil.getDateTimeString(yearSummaryEntity1.getMinValueTime()));
            result.put("3#机组年电量 最大值", String.valueOf(yearSummaryEntity1.getMaxValue()));
            result.put("3#机组年电量 最大值时间", DateUtil.getDateTimeString(yearSummaryEntity1.getMaxValueTime()));

            SummaryEntity yearSummaryEntity2 = historian.getNumberSummary(dynamo2EngcId, yearBeginTime, today);

            result.put("4#机组年电量 累计值", String.valueOf(yearSummaryEntity2.getTotalValue()));
            result.put("4#机组年电量 最小值", String.valueOf(yearSummaryEntity2.getMinValue()));
            result.put("4#机组年电量 最小值时间", DateUtil.getDateTimeString(yearSummaryEntity2.getMinValueTime()));
            result.put("4#机组年电量 最大值", String.valueOf(yearSummaryEntity2.getMaxValue()));
            result.put("4#机组年电量 最大值时间", DateUtil.getDateTimeString(yearSummaryEntity2.getMaxValueTime()));

            //获取月合计电量
            SummaryEntity monthSummaryEntity1 = historian.getNumberSummary(dynamo1EngcId, monthBeginTime, today);

            result.put("3#机组月电量 累计值", String.valueOf(monthSummaryEntity1.getTotalValue()));
            result.put("3#机组月电量 最小值", String.valueOf(monthSummaryEntity1.getMinValue()));
            result.put("3#机组月电量 最小值时间", DateUtil.getDateTimeString(monthSummaryEntity1.getMinValueTime()));
            result.put("3#机组月电量 最大值", String.valueOf(monthSummaryEntity1.getMaxValue()));
            result.put("3#机组月电量 最大值时间", DateUtil.getDateTimeString(monthSummaryEntity1.getMaxValueTime()));

            SummaryEntity monthSummaryEntity2 = historian.getNumberSummary(dynamo2EngcId, monthBeginTime, today);

            result.put("4#机组月电量 累计值", String.valueOf(monthSummaryEntity2.getTotalValue()));
            result.put("4#机组月电量 最小值", String.valueOf(monthSummaryEntity2.getMinValue()));
            result.put("4#机组月电量 最小值时间", DateUtil.getDateTimeString(monthSummaryEntity2.getMinValueTime()));
            result.put("4#机组月电量 最大值", String.valueOf(monthSummaryEntity2.getMaxValue()));
            result.put("4#机组月电量 最大值时间", DateUtil.getDateTimeString(monthSummaryEntity2.getMaxValueTime()));

        } catch (Exception ex) {
            result.put("异常", ex.getMessage());
        }

        return result;
    }

    /**
     * 单台机组/单个电站实时数据
     */
    private static class DynamoRealData {
        /**
         * 今天的日期，精确到日
         */
        Date today;
        /**
         * 本年起始电量
         */
        double yearBeginEngc;
        /**
         * 本月起始电量
         */
        double monthBeginEngc;
        /**
         * 昨日起始电量
         */
        double yestodayBeginEngc;
        /**
         * 今日起始电量
         */
        double todayBeginEngc;
        /**
         * 当前累计电量，实时值
         */
        double engc;
        /**
         * 当前负荷，实时值
         */
        double mw;
        /**
         * NOx
         */
        private double nox;
        /**
         * 烟尘
         */
        private double smoke;
        /**
         * SO2
         */
        private double so2;

        //2025-10-13，增加直接赋值年合计电量
        double yearSumEngc;

        /**
         * 本年电量
         */
        public double getYearEngc() {
            //本年电量=当前累计电量-本年起始电量
            //return engc - yearBeginEngc;
            //2025-10-13，修改由相减计算为直接赋值
            return yearSumEngc * 10.0f;
        }

        /**
         * 本月电量
         */
        public double getMonthEngc() {
            //本月电量=当前累计电量-本月起始电量
            //return engc - monthBeginEngc;
            //2025-10-14，经过与李晓燕实测发现变比是60，原先在web端乘以6导致电量少了10倍，在此进行处理
            return (engc - monthBeginEngc) * 10.0f;
        }

        /**
         * 今日电量=当前累计电量-今日起始电量
         */
        public double getTodayEngc() {
            //return engc - todayBeginEngc;
            //2025-10-14，经过与李晓燕实测发现变比是60，原先在web端乘以6导致电量少了10倍，在此进行处理
            return (engc - todayBeginEngc) * 10.0f;
        }

        /**
         * 昨日电量=今日起始电量-昨日起始电量
         */
        public double getyestodayEngc() {
            //return todayBeginEngc - yestodayBeginEngc;
            //2025-10-14，经过与李晓燕实测发现变比是60，原先在web端乘以6导致电量少了10倍，在此进行处理
            return (todayBeginEngc - yestodayBeginEngc) * 10.0f;
        }

        // 构造函数，初始化其他字段
        public DynamoRealData() {
            this.today = null; // 今天的日期
            this.yearBeginEngc = 0.0; // 本年起始电量
            this.monthBeginEngc = 0.0; // 本月起始电量
            this.yestodayBeginEngc = 0.0; // 昨日起始电量
            this.todayBeginEngc = 0.0; // 今日起始电量
            this.engc = 0.0; // 当前累计电量
            this.mw = 0.0; // 当前负荷
        }
    }

    /**
     * 缓存的第1台机组实时数据
     */
    private static DynamoRealData dynamo1RealData = new DynamoRealData();   // 3#机组数据
    /**
     * 缓存的第2台机组实时数据
     */
    private static DynamoRealData dynamo2RealData = new DynamoRealData();   // 4#机组数据

    /**
     * 缓存的当天全场实际负荷过程，按15分钟为间隔处理最终结果
     */
    private static List<GenericKeyValuePairDto<Date, Double>> dayActualMws = new ArrayList<>();

    /**
     * 记录最后1次处理当天全场实际负荷过程的时间点
     */
    private static Date latestHandleDayActualMwsTime = null;

    /**
     * 根据传入的日期字符串进行电厂实时数据查询，如果没有传入日期字符串或传入错误默认使用当天时间
     * @param dateString 日期字符串
     * @return qc.module.cms.dto.leddisplay.PlantRealDataDto
     * @author QuCheng Tech
     */
    PlantRealDataDto getDynamoRealDatas(String dateString) throws Exception {
        //日期默认为当天
        Date date = DateUtil.getNowDate();
        if (!StringUtils.isBlank(dateString)) {
            //如果有输入日期进行转换，转换失败不进行异常处理
            Date d = DateUtil.parseDate(dateString);
            if (d != null) date = d;
        }

        //从接口模拟数据
        return getYzhSimularDynamoRealDatas(date);
        //从阳宗海SIS系统提供的接口中获取数据
        //return getYzhSisDynamoDatas(date);
    }

    /**
     * 查询阳宗海公司模拟机组数据
     * @param date:
     * @return List<YzhDynamoRealDataDto>
     * @author QcCheng Tech
     */
    PlantRealDataDto getYzhSimularDynamoRealDatas(Date date) {

        // 模拟机组3年发电量范围 (单位: kWh)
        double minAnnualGeneration1 = 200000;   // 20万 kWh
        double maxAnnualGeneration1 = 3000000;  // 300万 kWh

        // 模拟机组4年发电量范围 (单位: kWh)
        double minAnnualGeneration2 = 200000;   // 20万 kWh
        double maxAnnualGeneration2 = 3000000;  // 300万 kWh

        // 创建 Random 实例
        Random random = new Random();

        // 随机生成机组3和机组4的年发电量
        double annualGeneration1 = minAnnualGeneration1 + (maxAnnualGeneration1 - minAnnualGeneration1) * random.nextDouble();
        double annualGeneration2 = minAnnualGeneration2 + (maxAnnualGeneration2 - minAnnualGeneration2) * random.nextDouble();

        // 模拟机组3和机组4的月发电量（年发电量 / 12）
        double monthlyGeneration1 = annualGeneration1 / 12;
        double monthlyGeneration2 = annualGeneration2 / 12;

        // 模拟机组3和机组4的日发电量（月发电量 / 30）
        double dailyGeneration1 = monthlyGeneration1 / 30;
        double dailyGeneration2 = monthlyGeneration2 / 30;

        //模拟机组3和机组4的昨日发电量（假设发电量在日发电量的±10%之间波动）
        double yesterdayGeneration1 = dailyGeneration1 * (1 + (random.nextDouble() * 0.2 - 0.1));
        double yesterdayGeneration2 = dailyGeneration2 * (1 + (random.nextDouble() * 0.2 - 0.1));

        // 模拟机组3假设负荷波动
        double minLoad = 100;  // 最小负荷
        double maxLoad = 200;  // 最大负荷
        double realTimeLoad1 = minLoad + (maxLoad - minLoad) * random.nextDouble();  // 随机生成实时负荷

        // 模拟机组4负荷波动
        double minLoad1 = 100;  // 最小负荷
        double maxLoad1 = 200;  // 最大负荷
        double realTimeLoad2 = minLoad1 + (maxLoad1 - minLoad1) * random.nextDouble();  // 随机生成实时负荷


        //构建返回结果集
        PlantRealDataDto PlantRealDataDto = new PlantRealDataDto();
        //定义机组数据和机组信息集合
        List<YzhDynamoRealDataDto> datas = new ArrayList<>();

        //3机组数据
        YzhDynamoRealDataDto dynamos1 = new YzhDynamoRealDataDto();
        dynamos1.setName("#3机组");
        dynamos1.setCapacity(300.0f);
        dynamos1.setMw(realTimeLoad1);
        dynamos1.setEngcyear(annualGeneration1);
        dynamos1.setEngcmonth(monthlyGeneration1);
        dynamos1.setEngctoday(dailyGeneration1);
        dynamos1.setEngcyestoday(yesterdayGeneration1);
        datas.add(dynamos1);

        //4机组数据
        YzhDynamoRealDataDto dynamos2 = new YzhDynamoRealDataDto();
        dynamos2.setName("#4机组");
        dynamos2.setCapacity(300.0f);
        dynamos2.setMw(realTimeLoad2);
        dynamos2.setEngcyear(annualGeneration2);
        dynamos2.setEngcmonth(monthlyGeneration2);
        dynamos2.setEngctoday(dailyGeneration2);
        dynamos2.setEngcyestoday(yesterdayGeneration2);
        datas.add(dynamos2);


        //添加到结果集
        YzhDynamoRealDataDto station = new YzhDynamoRealDataDto();
        station.setName("国能阳宗海发电有限公司");
        station.setCapacity(dynamos1.getCapacity() + dynamos2.getCapacity());//装机总容量，单位：MW
        station.setEngcyestoday(dynamos1.getEngcyestoday() + dynamos2.getEngcyestoday());//昨日总电量，单位：万kWh
        station.setMw(dynamos1.getMw() + dynamos2.getMw());//总负荷，单位：MW
        station.setEngcyear(dynamos1.getEngcyear() + dynamos2.getEngcyear());//本年总电量，单位：万kWh
        station.setEngcmonth(dynamos1.getEngcmonth() + dynamos2.getEngcmonth());//本月总电量，单位：万kWh
        station.setEngctoday(dynamos1.getEngctoday() + dynamos2.getEngctoday());//今日总电量，单位：万kWh


        PlantRealDataDto.setStation(station);
        PlantRealDataDto.setDynamos(datas);
        return PlantRealDataDto;
    }

    /**
     * 查询阳宗海公司SIS机组数据
     * <p>
     * 1.调SIS接口，取实时负荷、实时电量
     * * 2.调SIS接口成功：
     * *    2.1.缓存为空：new对象，实时负荷、实时电量赋值，调SIS接口获取本年、本月、昨日、今日起始电量（调SIS接口成功时更新缓存中的起始电量和今日日期）
     * *    2.2.缓存不为空：判断date和缓存中today年、月、日是否变化，任意一个变化时调SIS接口获取本年、本月、昨日、今日起始电量（调SIS接口成功时更新缓存的起始电量和今日日期）
     * * 更新缓存中的实时负荷和实时电量；
     * @param date:
     * @return List<YzhDynamoRealDataDto>
     * @author QcCheng Tech
     */
    PlantRealDataDto getYzhSisDynamoDatas(Date date) throws Exception {
        //获取单个数据库连接
        ServerImpl server = new ServerImpl("10.113.96.14", 6327, "sa", "VeStore-123#!");
        //历史查询服务实现类
        HistorianImpl historian = new HistorianImpl(server);
        //定义阳宗海SIS中的点号
        //负荷点号
        final int dynamo1MwId = 63479;//3#机组负荷
        final int dynamo2MwId = 66030;//4#机组负荷
        //电量点号
        final int dynamo1EngcId = 76709;//3#机组电量 DL7.DLAI7017
        final int dynamo2EngcId = 76713;//4#机组电量 DL7.DLAI7021
        //环保点号
        final int dynamo1So2Id = 63489;//3# SO2 CHHYQLND.TL3
        final int dynamo1NoxId = 63490;//3# NOx CHHYQNND.TL3
        final int dynamo1SmokeId = 63491;//3# 烟尘 CHHYQYCN.TL3
        final int dynamo2So2Id = 66027;//4# SO2 DHHYQLND.TL4
        final int dynamo2NoxId = 66029;//4# NOx DHHYQNND.TL4
        final int dynamo2SmokeId = 66018;//4# 烟尘 DHHYQYCN.TL4
        //获取日电量数据延迟分钟数
        final int getDayEngcDelayMinutes = 15;

        //查询时间段（当日初始时间）
        Date today = DateUtil.getDayDate(date);

        /**
         * 从SIS数据库获取数据及处理的流程
         * 1.获取2台机组的实时负荷和电量
         * 2.判断是否需要获取本年起始电量：
         * 2.1.判断条件：缓存的机组数据为null、缓存的机组数据中的日期为null、缓存的机组数据中的日期与本次查询的日期年份不是同一年
         * 2.2.处理流程：如果年份变化，本年、本月、昨日、今日的起始电量均需要重新获取
         * 3.判断是否需要获取本月起始电量：
         * 3.1.判断条件：缓存的机组数据中的日期与本次查询的日期的月份不是同一月；如果年份变化在第2步中已进行处理
         * 3.2.处理流程：如果月份变化，本月、昨日、今日的起始电量均需要重新获取
         * 4.判断是否需要获取昨日、今日起始电量：
         * 4.1.判断条件：缓存的机组数据中的日期与本次查询的日期的日不是同一日；如果年份或月份变化已经在第2步或第3步中已进行处理
         * 4.2.处理流程：昨日、今日的起始电量均需要重新获取；
         */

        //步骤1：获取2台机组的实时负荷和电量
        //此处应该调用查询实时数据接口
        try {
            //获取SIS数据库数据 获取实时负荷与实时电量
            //获取最新数据指定的时间为系统当前时间，获取时间点往前最近1条数据
            List<RtdbData> dbDatas = historian.getCrossSectionValues(new int[]{dynamo1MwId, dynamo2MwId, dynamo1EngcId, dynamo2EngcId, dynamo1So2Id, dynamo2So2Id, dynamo1NoxId, dynamo2NoxId, dynamo1SmokeId, dynamo2SmokeId}, DateUtil.addHours(DateUtil.getNowDate(), 0x1), RtdbHisMode.RTDB_PREVIOUS);
            if (dbDatas != null && dbDatas.size() > 0x0) {
                for (RtdbData data : dbDatas) {
                    int id = data.getId();
                    Double value = (Double) data.getValue();
                    Date tm = data.getDate();
                    System.out.println("调用SIS获取实时负荷与实时电量返回的数据项，Id=" + id + "，Tm=" + DateUtil.getDateTimeString(tm) + "，Value=" + value);

                    // 处理实时负荷数据赋值
                    switch (id) {
                        case dynamo1MwId:
                            dynamo1RealData.mw = value;
                            break;
                        case dynamo2MwId:
                            dynamo2RealData.mw = value;
                            break;
                        case dynamo1EngcId:
                            dynamo1RealData.engc = value;
                            break;
                        case dynamo2EngcId:
                            dynamo2RealData.engc = value;
                            break;
                        case dynamo1So2Id:
                            dynamo1RealData.so2 = value;
                            break;
                        case dynamo2So2Id:
                            dynamo2RealData.so2 = value;
                            break;
                        case dynamo1NoxId:
                            dynamo1RealData.nox = value;
                            break;
                        case dynamo2NoxId:
                            dynamo2RealData.nox = value;
                            break;
                        case dynamo1SmokeId:
                            dynamo1RealData.smoke = value;
                            break;
                        case dynamo2SmokeId:
                            dynamo2RealData.smoke = value;
                            break;
                        default:
                            System.out.println("调用SIS获取实时负荷与实时电量错误，返回的数据集合点号不是预期结果，Id=" + id + "，Value=" + value);
                            break;
                    }
                }
            } else {
                System.out.println("调用SIS获取实时负荷与实时电量错误，返回的数据集合为空");
            }
        } catch (Exception ex) {
            System.out.println("调用SIS获取实时负荷与实时电量异常，" + ex.getMessage());
        }

        //步骤2-4：判断是否需要获取本年、本月、今日起始电量
        boolean needGetYearBeginEngc = false;
        boolean needGetMonthBeginEngc = false;
        boolean needGetDayBeginEngc = false;
        //缓存的数据判断任意1台机组即可，2台机组的数据日期保持同步
        if (dynamo1RealData == null || dynamo1RealData.today == null || DateUtil.getYear(dynamo1RealData.today) != DateUtil.getYear(today)) {
            needGetYearBeginEngc = true;
            needGetMonthBeginEngc = true;
            needGetDayBeginEngc = true;
        }

        //如果不需要获取年起始电量，判断是否需要获取月起始电量
        if (needGetYearBeginEngc == false) {
            if (DateUtil.getMonth(dynamo1RealData.today) != DateUtil.getMonth(today)) {
                //如果月份变化，需要重新获取月起始电量；同时也不需要获取昨日和今日起始电量
                needGetMonthBeginEngc = true;
                needGetDayBeginEngc = true;
            } else if (DateUtil.getDay(dynamo1RealData.today) != DateUtil.getDay(today)) {
                //如果月份没有变化，判断日期是否变化
                needGetDayBeginEngc = true;
            }
        }
        //2025-2-17，修改增加电量采集入库的时间可能会有延迟，如果0：00去获取累计电量可能会出现获取到的电量数据是0点前的电量问题，导致使用该值进行统计出现数值错误；
        // 判断如果当前时间在00:00~00：n分钟中内，重复进行今日电量的获取
        if (DateUtil.getHour(date) == 0x0 && DateUtil.getMinute(date) <= getDayEngcDelayMinutes) {
            //今日电量必须要获取
            needGetDayBeginEngc = true;
            //如果日期为1时还需要获取月电量
            if (DateUtil.getDay(date) == 0x1)
                needGetMonthBeginEngc = true;
            //如果月份为1时还需要获取年电量
            if (DateUtil.getMonth(date, true) == 0x1)
                needGetYearBeginEngc = true;
        }
        System.out.println("判断获取历史时刻起始电量，今日=" + DateUtil.getDateString(today) + "，需获取本年=" + needGetYearBeginEngc + "，需获取本月=" + needGetMonthBeginEngc + "，需获取今日=" + needGetDayBeginEngc);

        //步骤2：获取本年电量--只获取本年，后面再根据是否需要获取本月和今日电量标记再进行判断获取
        if (needGetYearBeginEngc) {
            try {
                Date yearBeginTime = DateUtil.newDate(DateUtil.getYear(date), 0, 1);

                //getCrossSectionValues：批量获取标签点在某一时间的历史断面数据
                //RtdbHisMode.RTDB_PREVIOUS：寻找上一个最近的数据；指定的时间点不包含在获取数据的时间范围内，因此指定的时间往后1秒；
                List<RtdbData> beginYearEngcDatas = historian.getCrossSectionValues(new int[]{dynamo1EngcId, dynamo2EngcId}, DateUtil.addSeconds(yearBeginTime, 0x1), RtdbHisMode.RTDB_PREVIOUS);
                if (beginYearEngcDatas != null && beginYearEngcDatas.size() > 0x0) {
                    //遍历返回结果数据进行处理
                    for (RtdbData data : beginYearEngcDatas) {
                        int id = data.getId();
                        Double value = (Double) data.getValue();
                        Date tm = data.getDate();
                        System.out.println("调用SIS获取本年起始电量返回的数据项，Id=" + id + "，Tm=" + DateUtil.getDateTimeString(tm) + "，Value=" + value);

                        switch (id) {
                            case dynamo1EngcId:
                                //如果获取到本年起始电量数据后，对缓存中的日期进行更新
                                dynamo1RealData.today = today;
                                dynamo1RealData.yearBeginEngc = value;
                                break;
                            case dynamo2EngcId:
                                //如果获取到本年起始电量数据后，对缓存中的日期进行更新
                                dynamo2RealData.today = today;
                                dynamo2RealData.yearBeginEngc = value;
                                break;
                            default:
                                System.out.println("调用SIS获取本年起始电量错误，返回的数据集合点号不是预期结果，Id=" + id + "，Value=" + value);
                                break;
                        }
                    }
                } else {
                    System.out.println("调用SIS获取本年起始电量错误，返回的数据集合为空");
                }
            } catch (Exception ex) {
                System.out.println("调用SIS获取本年起始电量异常，" + ex.getMessage());
            }
        }

        //步骤3：获取本月电量
        if (needGetMonthBeginEngc) {
            try {
                Date monthBeginTime = DateUtil.newDate(DateUtil.getYear(date), DateUtil.getMonth(date, false), 1);

                List<RtdbData> beginMonthEngcDatas = historian.getCrossSectionValues(new int[]{dynamo1EngcId, dynamo2EngcId}, DateUtil.addSeconds(monthBeginTime, 0x1), RtdbHisMode.RTDB_PREVIOUS);
                if (beginMonthEngcDatas != null && beginMonthEngcDatas.size() > 0x0) {
                    //遍历返回结果数据进行处理
                    for (RtdbData data : beginMonthEngcDatas) {
                        int id = data.getId();
                        Double value = (Double) data.getValue();
                        Date tm = data.getDate();
                        System.out.println("调用SIS获取本月起始电量返回的数据项，Id=" + id + "，Tm=" + DateUtil.getDateTimeString(tm) + "，Value=" + value);

                        switch (id) {
                            case dynamo1EngcId:
                                //如果获取到本月起始电量数据后，对缓存中的日期进行更新
                                dynamo1RealData.today = today;
                                dynamo1RealData.monthBeginEngc = value;
                                break;
                            case dynamo2EngcId:
                                //如果获取到本月起始电量数据后，对缓存中的日期进行更新
                                dynamo2RealData.today = today;
                                dynamo2RealData.monthBeginEngc = value;
                                break;
                            default:
                                System.out.println("调用SIS获取本月起始电量错误，返回的数据集合点号不是预期结果，Id=" + id + "，Value=" + value);
                                break;
                        }
                    }
                } else {
                    System.out.println("调用SIS获取本月起始电量错误，返回的数据集合为空");
                }
            } catch (Exception ex) {
                System.out.println("调用SIS获取本月起始电量异常，" + ex.getMessage());
            }
        }

        //步骤4：获取昨日和今日电量
        if (needGetDayBeginEngc) {
            //获取昨日起始电量
            try {
                Date yestodayBeginTime = DateUtil.addDays(today, -1);

                List<RtdbData> beginYestodayEngcDatas = historian.getCrossSectionValues(new int[]{dynamo1EngcId, dynamo2EngcId}, DateUtil.addSeconds(yestodayBeginTime, 0x1), RtdbHisMode.RTDB_PREVIOUS);
                if (beginYestodayEngcDatas != null && beginYestodayEngcDatas.size() > 0x0) {
                    //遍历返回结果数据进行处理
                    for (RtdbData data : beginYestodayEngcDatas) {
                        int id = data.getId();
                        Double value = (Double) data.getValue();
                        Date tm = data.getDate();
                        System.out.println("调用SIS获取昨日起始电量返回的数据项，Id=" + id + "，Tm=" + DateUtil.getDateTimeString(tm) + "，Value=" + value);

                        switch (id) {
                            case dynamo1EngcId:
                                dynamo1RealData.yestodayBeginEngc = value;
                                break;
                            case dynamo2EngcId:
                                dynamo2RealData.yestodayBeginEngc = value;
                                break;
                            default:
                                System.out.println("调用SIS获取昨日起始电量错误，返回的数据集合点号不是预期结果，Id=" + id + "，Value=" + value);
                                break;
                        }
                    }
                } else {
                    System.out.println("调用SIS获取昨日起始电量错误，返回的数据集合为空");
                }
            } catch (Exception ex) {
                System.out.println("调用SIS获取昨日起始电量异常，" + ex.getMessage());
            }

            //获取今日起始电量
            try {
                List<RtdbData> beginTodayEngcDatas = historian.getCrossSectionValues(new int[]{dynamo1EngcId, dynamo2EngcId}, DateUtil.addSeconds(today, 0x1), RtdbHisMode.RTDB_PREVIOUS);
                if (beginTodayEngcDatas != null && beginTodayEngcDatas.size() > 0x0) {
                    //遍历返回结果数据进行处理
                    for (RtdbData data : beginTodayEngcDatas) {
                        int id = data.getId();
                        Double value = (Double) data.getValue();
                        Date tm = data.getDate();
                        System.out.println("调用SIS获取今日起始电量返回的数据项，Id=" + id + "，Tm=" + DateUtil.getDateTimeString(tm) + "，Value=" + value);

                        switch (id) {
                            case dynamo1EngcId:
                                //如果获取到今日起始电量数据后，对缓存中的日期进行更新
                                dynamo1RealData.today = today;
                                dynamo1RealData.todayBeginEngc = value;
                                break;
                            case dynamo2EngcId:
                                //如果获取到本月起始电量数据后，对缓存中的日期进行更新
                                dynamo2RealData.today = today;
                                dynamo2RealData.todayBeginEngc = value;
                                break;
                            default:
                                System.out.println("调用SIS获取今日起始电量错误，返回的数据集合点号不是预期结果，Id=" + id + "，Value=" + value);
                                break;
                        }
                    }
                } else {
                    System.out.println("调用SIS获取今日起始电量错误，返回的数据集合为空");
                }
            } catch (Exception ex) {
                System.out.println("调用SIS获取今日起始电量异常，" + ex.getMessage());
            }
        }

        //2025-10-14，确定截止14日0点全厂累计电量为184411.39万kwh，使用当前时间的累计电量减去14日0点的累计电量 再加上已知的全厂年累计电量进行计算
        //对截止14日0点全厂累计电量为1844.11.39万kwh分解：
        //电量单位换算：在全厂年累计中乘以*10，在web端乘以6；因此需要对184411.39万kwh同样进行转换处理
        //3#机截止14日0点累计值为110.8995
        dynamo1RealData.yearSumEngc = 100000 / 60.0f + (dynamo1RealData.engc - 110.8995);
        //4#机截止14日0点累计值为0
        dynamo2RealData.yearSumEngc = (184411.39 - 100000) / 60.0f + (dynamo2RealData.engc - 0.0);
        //2025-10-14，临时使用固定值
        //dynamo1RealData.yearSumEngc = 100000 / 6.0f;
        //dynamo2RealData.yearSumEngc = 84411.39 / 6.0f;

        //调试输出对应时间点的累计电量值
        System.out.println("3#机组电量，累计=" + dynamo1RealData.engc + "，本年=" + dynamo1RealData.yearBeginEngc + "，本月=" + dynamo1RealData.monthBeginEngc + "，昨日=" + dynamo1RealData.yestodayBeginEngc + "，今日=" + dynamo1RealData.todayBeginEngc);
        System.out.println("4#机组电量，累计=" + dynamo2RealData.engc + "，本年=" + dynamo2RealData.yearBeginEngc + "，本月=" + dynamo2RealData.monthBeginEngc + "，昨日=" + dynamo2RealData.yestodayBeginEngc + "，今日=" + dynamo2RealData.todayBeginEngc);

        //关闭连接
        server.close();

        //构建返回结果集
        PlantRealDataDto result = new PlantRealDataDto();

        //定义机组数据和机组信息集合
        List<YzhDynamoRealDataDto> datas = new ArrayList<>();
        //构建3#机组结果集
        YzhDynamoRealDataDto dynamo1Data = new YzhDynamoRealDataDto();
        dynamo1Data.setName("#3机组");//机组名称
        dynamo1Data.setCapacity(300.0f);//装机容量，单机容量，单位：MW
        dynamo1Data.setMw(dynamo1RealData.mw);
        dynamo1Data.setSo2(dynamo1RealData.so2);
        dynamo1Data.setNox(dynamo1RealData.nox);
        dynamo1Data.setSmoke(dynamo1RealData.smoke);
        dynamo1Data.setEngcyear(dynamo1RealData.getYearEngc());
        dynamo1Data.setEngcmonth(dynamo1RealData.getMonthEngc());
        dynamo1Data.setEngcyestoday(dynamo1RealData.getyestodayEngc());
        dynamo1Data.setEngctoday(dynamo1RealData.getTodayEngc());
        datas.add(dynamo1Data);

        //构建4#机组结果集
        YzhDynamoRealDataDto dynamo2Data = new YzhDynamoRealDataDto();
        dynamo2Data.setName("#4机组");//机组名称
        dynamo2Data.setCapacity(300.0f);//装机容量，单机容量，单位：MW
        dynamo2Data.setMw(dynamo2RealData.mw);
        dynamo2Data.setSo2(dynamo2RealData.so2);
        dynamo2Data.setNox(dynamo2RealData.nox);
        dynamo2Data.setSmoke(dynamo2RealData.smoke);
        dynamo2Data.setEngcyear(dynamo2RealData.getYearEngc());
        dynamo2Data.setEngcmonth(dynamo2RealData.getMonthEngc());
        dynamo2Data.setEngcyestoday(dynamo2RealData.getyestodayEngc());
        dynamo2Data.setEngctoday(dynamo2RealData.getTodayEngc());
        datas.add(dynamo2Data);

        //全厂数据集合
        YzhDynamoRealDataDto station = new YzhDynamoRealDataDto();
        station.setCapacity(dynamo1Data.getCapacity() + dynamo2Data.getCapacity());//装机总容量，单位：MW
        station.setEngcyestoday(dynamo1Data.getEngcyestoday() + dynamo2Data.getEngcyestoday());
        station.setMw(dynamo1Data.getMw() + dynamo2Data.getMw());
        station.setEngcyear(dynamo1Data.getEngcyear() + dynamo2Data.getEngcyear());
        station.setEngcmonth(dynamo1Data.getEngcmonth() + dynamo2Data.getEngcmonth());
        station.setEngctoday(dynamo1Data.getEngctoday() + dynamo2Data.getEngctoday());
        station.setEngcyestoday(dynamo1Data.getEngcyestoday() + dynamo2Data.getEngcyestoday());
        station.setName("国能阳宗海发电有限公司");

        result.setStation(station);
        result.setDynamos(datas);

        return result;
    }

    /**
     * 2025年4月起使用，用于获取阳宗海生产数据；
     * 包括最新、当日、当月、当年数据；
     *
     * @param id 传入日期，为空时使用当天
     * @return qc.module.demo.dto.powerplant.YzhProductionDataDto
     * @author QuCheng Tech
     * @since 2025/4/9
     */
    @RequestMapping(value = "/yzhproduct2504", method = {RequestMethod.GET})
    public YzhProductionDataDto getYzhProductionDatasByParam(@RequestParam(value = "id", required = false) String id) throws Exception {
        return getYzhProductionDatas(id);
    }

    /**
     * 2025年4月起使用，用于获取阳宗海生产数据；
     * 包括最新、当日、当月、当年数据；
     * @param id 传入日期，为空时使用当天
     * @return qc.module.demo.dto.powerplant.YzhProductionDataDto
     * @author QuCheng Tech
     * @since 2025/4/9
     */
    @RequestMapping(value = "/yzhproduct2504/{id}", method = {RequestMethod.GET})
    public YzhProductionDataDto getYzhProductionDatasByPath(@PathVariable(value = "id", required = false) String id) throws Exception {
        return getYzhProductionDatas(id);
    }

    /**
     * 2025年4月起使用，用于获取阳宗海生产数据；
     * @param dateString 指定的日期字符串，为空时默认获取当天
     * @return qc.module.demo.dto.powerplant.YzhProductionDataDto
     * @author QuCheng Tech
     * @since 2025/4/22
     */
    YzhProductionDataDto getYzhProductionDatas(String dateString) throws Exception {
        //日期默认为当天
        Date date = DateUtil.getNowDate();
        if (!StringUtils.isBlank(dateString)) {
            //如果有输入日期进行转换，转换失败不进行异常处理
            Date d = DateUtil.parseDate(dateString);
            if (d != null) date = d;
        }

        //从接口模拟数据
        return getYzhSimularProductionDatas(date);
        //获取阳宗海生产实际数据
        //return getYzhActualProductionDatas(date);
    }

    /**
     * 获取阳宗海生产数据--实际真实数据
     * @param date 指定的日期
     * @return qc.module.demo.dto.powerplant.YzhProductionDataDto
     * @author QuCheng Tech
     * @since 2025/4/22
     */
    YzhProductionDataDto getYzhActualProductionDatas(Date date) throws Exception {
        System.out.println("开始获取阳宗海生产数据，查询日期：" + date);
        /**
         * 实际生产数据获取来源
         * 1.SIS数据库：2台机组最新实时数据（有功、So2、NOX、烟尘）、2台机组当天负荷过程（用于计算全厂实际负荷过程）
         * 2.点号数据表中的数据：计划发电量（日、月、年）--对应时间点、煤量（来煤、耗煤、存煤）--对应时间点最近1条、当天计划负荷过程
         *
         * 数据获取及处理步骤
         * 1.1.从SIS数据库获取2台机组最新实时数据；调用方法中已计算全厂实时负荷、全厂日月年电量
         * 1.2.从SIS数据库获取2台机组当日负荷过程，按15分钟间隔规整为实际负荷过程集合
         * 2.1.从点号数据表获取计划发电量（日、月、年）--对应时间点
         * 2.2从点号数据表获取煤量（来煤、耗煤、存煤）--对应时间点最近1条
         * 2.3从点号数据表获取当天计划负荷过程--返回集合固定为96点
         */
        YzhProductionDataDto result = new YzhProductionDataDto();
        YzhProductionReservoirDataDto reservoirData = new YzhProductionReservoirDataDto();
        //阳宗海电厂固定为2台机组
        YzhProductionDynamoDataDto dynamoData1 = new YzhProductionDynamoDataDto();
        YzhProductionDynamoDataDto dynamoData2 = new YzhProductionDynamoDataDto();
        //1.1.从SIS数据库获取2台机组最新实时数据；调用方法中已计算全厂实时负荷、全厂日月年电量
        try {
            PlantRealDataDto yzhSisDynamoDatas = getYzhSisDynamoDatas(date);
            System.out.println("SIS机组数据获取结果：" + (yzhSisDynamoDatas != null ? "成功" : "无数据"));
            if (yzhSisDynamoDatas != null) {
                if (yzhSisDynamoDatas.getStation() != null) {
                    //获取全厂数据
                    reservoirData.setName(yzhSisDynamoDatas.getStation().getName());
                    reservoirData.setCapacity(yzhSisDynamoDatas.getStation().getCapacity());
                    reservoirData.setMw(yzhSisDynamoDatas.getStation().getMw());
                    reservoirData.setEngcyestoday(yzhSisDynamoDatas.getStation().getEngcyestoday());
                    reservoirData.setEngctoday(yzhSisDynamoDatas.getStation().getEngctoday());
                    reservoirData.setEngcmonth(yzhSisDynamoDatas.getStation().getEngcmonth());
                    reservoirData.setEngcyear(yzhSisDynamoDatas.getStation().getEngcyear());
                } else {
                    System.out.println("警告：未获取到电厂数据(Station为null)");
                }

                //获取2台机组数据
                if (yzhSisDynamoDatas.getDynamos() != null) {
                    if (yzhSisDynamoDatas.getDynamos().size() > 0x0) {
                        YzhDynamoRealDataDto dynamoRealDataDto = yzhSisDynamoDatas.getDynamos().get(0x0);

                        dynamoData1.setName(dynamoRealDataDto.getName());
                        dynamoData1.setCapacity(dynamoRealDataDto.getCapacity());
                        dynamoData1.setMw(dynamoRealDataDto.getMw());
                        dynamoData1.setSo2(dynamoRealDataDto.getSo2());
                        dynamoData1.setNox(dynamoRealDataDto.getNox());
                        dynamoData1.setSmoke(dynamoRealDataDto.getSmoke());
                    } else {
                        System.out.println("警告：未获取到第1台机组数据");
                    }
                    if (yzhSisDynamoDatas.getDynamos().size() > 0x1) {
                        YzhDynamoRealDataDto dynamoRealDataDto = yzhSisDynamoDatas.getDynamos().get(0x1);

                        dynamoData2.setName(dynamoRealDataDto.getName());
                        dynamoData2.setCapacity(dynamoRealDataDto.getCapacity());
                        dynamoData2.setMw(dynamoRealDataDto.getMw());
                        dynamoData2.setSo2(dynamoRealDataDto.getSo2());
                        dynamoData2.setNox(dynamoRealDataDto.getNox());
                        dynamoData2.setSmoke(dynamoRealDataDto.getSmoke());
                    } else {
                        System.out.println("警告：未获取到第2台机组数据");
                    }

                } else {
                    System.out.println("警告：未获取到任何机组数据(Dynamos为null)");
                }
            }
        } catch (Exception ex) {
            //SIS数据库查询失败，继续其他操作
            System.out.println("调用SIS获取实时负荷与实时电量异常，" + ex.getMessage());
        }

        //1.2.从SIS数据库获取2台机组当日负荷过程，按15分钟间隔规整为实际负荷过程集合
        reservoirData.setTodaymws(getDayActualMws(date));

        //2.1.从点号数据表获取计划发电量（日、月、年）--对应时间点
        //5.2 计划从cms中的点号表数值中获取(今日计划-1001,月计划-1002,年计划-1003)
        final String planEngcDayPointId = "1001";
        final String planEngcMonthPointId = "1002";
        final String planEngcYearPointId = "1003";

        //5.3 计算日期范围  年计划，月计划，日计划的查询条件dto
        Date yearTm = DateUtil.newDate(DateUtil.getYear(date), 0, 1, true);
        Date monthTm = DateUtil.newDate(DateUtil.getYear(date), DateUtil.getMonth(date), 1, false);
        Date dayTm = DateUtil.getDayDate(date);

        //5.4 从数据库查询计划电量
        GenericKeyValuePairDto<Date, Double> yearPlanPair = tsNumDataService.getByPointIdAndTm(planEngcYearPointId, yearTm, true);
        GenericKeyValuePairDto<Date, Double> monthPlanPair = tsNumDataService.getByPointIdAndTm(planEngcMonthPointId, monthTm, true);
        GenericKeyValuePairDto<Date, Double> dayPlanPair = tsNumDataService.getByPointIdAndTm(planEngcDayPointId, dayTm, true);

        //5.5 将计划数据填充到结果对象reservoirData中
        reservoirData.setPlanengcyear(yearPlanPair != null ? yearPlanPair.getValue() : NaN);
        reservoirData.setPlanengcmonth(monthPlanPair != null ? monthPlanPair.getValue() : NaN);
        reservoirData.setPlanengctoday(dayPlanPair != null ? dayPlanPair.getValue() : NaN);

        //2.2 从点号数据表获取煤量（来煤、耗煤、存煤）--对应时间点最近1条
        //5.6煤炭数据，cms中的点号数值表中获取(来煤-2001,存煤-2002,耗煤-2003)
        final String coalInPointId = "2001";
        final String coalOutPointId = "2002";
        final String coalUsePointId = "2003";

        //5.7 煤炭数量获取
        GenericKeyValuePairDto<Date, Double> inCoal = tsNumDataService.getByPointIdAndTm(coalInPointId, dayTm, true);
        GenericKeyValuePairDto<Date, Double> useCoal = tsNumDataService.getByPointIdAndTm(coalUsePointId, dayTm, true);
        GenericKeyValuePairDto<Date, Double> outCoal = tsNumDataService.getByPointIdAndTm(coalOutPointId, dayTm, true);

        //5.8 处理查询结果，将煤炭数量添加到reservoirData中
        reservoirData.setIncoal(inCoal != null ? inCoal.getValue() : NaN);
        reservoirData.setUsecoal(useCoal != null ? useCoal.getValue() : NaN);
        reservoirData.setStockcoal(outCoal != null ? outCoal.getValue() : NaN);

        //2.3 从点号数据表获取当天计划负荷过程-- 返回集合固定为96点
        Date dayBeginTime = dayTm;
        Date dayEndTime = DateUtil.addDays(dayBeginTime, 0x1);
        final String planMvPointId = "10001"; // 实时负荷计划点号
        List<GenericKeyValuePairDto<Date, Double>> planMwDatas = tsNumDataService.query(planMvPointId, dayTm, dayEndTime);
        System.out.println((planMwDatas == null || planMwDatas.isEmpty()) ? "计划负荷数据获取结果：空" + planMwDatas : "");
        //计划负荷过程不管实际有的数据情况，保证按间隔15分钟的96点均在返回集合中
        List<GenericKeyValuePairDto<Date, Double>> planMws = new ArrayList<>();
        while (dayBeginTime.after(dayEndTime) == false) {
            GenericKeyValuePairDto<Date, Double> kv = new GenericKeyValuePairDto();
            kv.setKey(dayBeginTime);
            kv.setValue(NaN);
            if (planMwDatas != null && planMwDatas.size() > 0x0) {
                //取对应时间点的数据，不一定存在对应时间点的数据，取时间点前最近的一条数据值
                Date finalDayBeginTime = dayBeginTime;
                List<GenericKeyValuePairDto<Date, Double>> noMoreThanTimeDatas = planMwDatas.stream().filter(p -> p.getKey().after(finalDayBeginTime) == false).collect(Collectors.toList());
                if (noMoreThanTimeDatas != null && noMoreThanTimeDatas.size() > 0x0) {
                    //取最后一条数据
                    kv.setValue(noMoreThanTimeDatas.get(noMoreThanTimeDatas.size() - 0x1).value);
                }
            }
            planMws.add(kv);

            dayBeginTime = DateUtil.addMinutes(dayBeginTime, 15);
        }
        reservoirData.setPlantodaymws(planMws);

        //返回结果赋值
        result.setReservoir(reservoirData);
        List<YzhProductionDynamoDataDto> dynamoDatas = new ArrayList<>();
        dynamoDatas.add(dynamoData1);
        dynamoDatas.add(dynamoData2);
        result.setDynamos(dynamoDatas);

        return result;
    }

    /**
     * 获取指定日期按15分钟间隔的电厂实时负荷数据，实际全厂发电过程截止时间不大于当前时间
     * 最终返回的数据以15分钟为间隔，如果上次获取数据的时间与本次获取数据的时间在同一个间隔周期内时不进行重复调用SIS数据库获取数据--使用记录的缓存数据
     * @param date 指定日期
     * @return 包含时间点和负荷值的键值对列表
     */
    List<GenericKeyValuePairDto<Date, Double>> getDayActualMws(Date date) {
        //数据间隔设置为15分钟
        int intervalMinutes = 15;
        Date now = DateUtil.getNowDate();
        //判断本次是否需要从SIS数据库中获取数据并进行日实际负荷过程的处理，如果不需要处理直接返回缓存集合
        boolean needHandle = false;
        if (latestHandleDayActualMwsTime == null) {
            needHandle = true;
        } else {
            //判断上次获取数据的时间和当前时间点是否在同一时段内
            Date latestHandleBeginTime = TimeSpanUtil.getBeginTime(latestHandleDayActualMwsTime, intervalMinutes);
            Date nowHandleBeginTime = TimeSpanUtil.getBeginTime(now, intervalMinutes);
            if (nowHandleBeginTime.after(latestHandleBeginTime))
                needHandle = true;
        }
        //如果缓存日负荷过程为空，本次进行数据获取和处理
        if (needHandle == false) {
            if (dayActualMws == null || dayActualMws.size() < 0x1)
                needHandle = true;
        }

        //如果本次不需要处理数据，直接返回缓存数据
        if (needHandle == false)
            return dayActualMws;

        //本次需要重新进行数据查询和处理
        List<GenericKeyValuePairDto<Date, Double>> result = new ArrayList<>();
        //查询数据的起始时间为传入日期的0点，截止时间不大于当前时间
        Date beginTime = DateUtil.getDayDate(date);
        Date endTime = DateUtil.addDays(beginTime, 0x1);
        if (endTime.after(now))
            endTime = now;
        ServerImpl server = null;
        try {
            // 获取数据库连接
            server = new ServerImpl("10.113.96.14", 6327, "sa", "VeStore-123#!");
            HistorianImpl historian = new HistorianImpl(server);

            // 定义点号
            final int dynamo1MwId = 63479; // 3#机组负荷
            final int dynamo2MwId = 66030; // 4#机组负荷

            // 根据实际数据条数获取全部数据
            List<RtdbData> dynamo1Data = historian.getArchivedValues(dynamo1MwId, 100000, beginTime, endTime);
            List<RtdbData> dynamo2Data = historian.getArchivedValues(dynamo2MwId, 100000, beginTime, endTime);

            if (dynamo1Data != null && dynamo1Data.size() > 0x0
                    && dynamo2Data != null && dynamo2Data.size() > 0x0) {
                Date time = beginTime;
                while (time.after(endTime) == false) {
                    //获取距离当前时间点往前最近1条数据，2台机组负荷值相加
                    double mw = 0.0f;
                    Date finalTime = time;
                    //获取第1台机组负荷值
                    List<RtdbData> filterByTime = dynamo1Data.stream().filter(m -> m.getDate().after(finalTime) == false).collect(Collectors.toList());
                    //如果根据时间不大于当前时间点无数据，默认使用查询结果中的第1条数据值
                    if (filterByTime != null && filterByTime.size() > 0x0) {
                        //SIS查询结果已按时间排序，获取最后1条
                        RtdbData defaultData = filterByTime.get(filterByTime.size() - 0x1);
                        mw += (Double) defaultData.getValue();
                    } else {
                        RtdbData defaultData = dynamo1Data.get(0x0);
                        mw += (Double) defaultData.getValue();
                    }
                    //获取第2台机组负荷值
                    filterByTime = dynamo2Data.stream().filter(m -> m.getDate().after(finalTime) == false).collect(Collectors.toList());
                    //如果根据时间不大于当前时间点无数据，默认使用查询结果中的第1条数据值
                    if (filterByTime != null && filterByTime.size() > 0x0) {
                        //SIS查询结果已按时间排序，获取最后1条
                        RtdbData defaultData = filterByTime.get(filterByTime.size() - 0x1);
                        mw += (Double) defaultData.getValue();
                    } else {
                        RtdbData defaultData = dynamo2Data.get(0x0);
                        mw += (Double) defaultData.getValue();
                    }

                    GenericKeyValuePairDto<Date, Double> kv = new GenericKeyValuePairDto();
                    kv.setKey(time);
                    kv.setValue(mw);
                    result.add(kv);

                    time = DateUtil.addMinutes(time, intervalMinutes);
                }
            }
        } catch (Exception e) {
            System.out.println("获取日实际负荷过程数据失败" + e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                if (server != null) {
                    server.close();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //更新缓存的负荷过程
        dayActualMws = result;

        //更新上次获取和处理数据时间为当前时间
        latestHandleDayActualMwsTime = now;

        return result;
    }

    /**
     * 模拟阳宗海生产数据方法
     * @param date 指定的日期
     * @return qc.module.demo.dto.powerplant.YzhProductionDataDto
     * @author QuCheng Tech
     * @since 2025/4/9
     */
    YzhProductionDataDto getYzhSimularProductionDatas(Date date) {
        YzhProductionDataDto result = new YzhProductionDataDto();

        //电厂全厂数据
        YzhProductionReservoirDataDto reservoirData = new YzhProductionReservoirDataDto();

        //各机组数据
        List<YzhProductionDynamoDataDto> dynamoDatas = new ArrayList<>();
        YzhProductionDynamoDataDto dynamoData1 = new YzhProductionDynamoDataDto();
        YzhProductionDynamoDataDto dynamoData2 = new YzhProductionDynamoDataDto();

        //模拟数据
        // 模拟机组3年发电量范围 (单位: 万kWh)
        double minYearEngc1 = 120000;   // 12 0000万 kWh
        double maxYearEngc1 = 150000;  // 15 0000万 kWh
        // 模拟机组4年发电量范围 (单位: 万kWh)
        double minYearEngc2 = 120000;   // 12 0000万 kWh
        double maxYearEngc2 = 150000;  // 15 0000万 kWh
        // 创建 Random 实例
        Random random = new Random();
        // 随机生成机组3和机组4的年发电量；单位换算在前端处理，=接口返回值*6
        double yearEngc1 = (minYearEngc1 + (maxYearEngc1 - minYearEngc1) * random.nextDouble()) / 6.0f;
        double yearEngc2 = (minYearEngc2 + (maxYearEngc2 - minYearEngc2) * random.nextDouble()) / 6.0f;
        double yearPlanEngc1 = (minYearEngc1 + (maxYearEngc1 - minYearEngc1) * random.nextDouble()) / 6.0f;
        double yearPlanEngc2 = (minYearEngc2 + (maxYearEngc2 - minYearEngc2) * random.nextDouble()) / 6.0f;
        // 模拟机组3和机组4的月发电量（年发电量 / 12）
        double monthEngc1 = yearEngc1 / 12;
        double monthEngc2 = yearEngc2 / 12;
        double monthPlanEngc1 = yearPlanEngc1 / 12;
        double monthPlanEngc2 = yearPlanEngc2 / 12;
        // 模拟机组3和机组4的日发电量（月发电量 / 30）
        double todayEngc1 = monthEngc1 / 30;
        double todayEngc2 = monthEngc2 / 30;
        double todayPlanEngc1 = monthPlanEngc1 / 30;
        double todayPlanEngc2 = monthPlanEngc2 / 30;
        //模拟机组3和机组4的昨日发电量（假设发电量在日发电量的±10%之间波动）
        double yesterdayEngc1 = todayEngc1 * (1 + (random.nextDouble() * 0.2 - 0.1));
        double yesterdayEngc2 = todayEngc2 * (1 + (random.nextDouble() * 0.2 - 0.1));
        // 模拟机组3假设负荷波动
        double minDynamoMw = 100;  // 最小负荷
        double maxDynamoMw = 200;  // 最大负荷
        double mw1 = minDynamoMw + (maxDynamoMw - minDynamoMw) * random.nextDouble();  // 随机生成实时负荷
        double mw2 = minDynamoMw + (maxDynamoMw - minDynamoMw) * random.nextDouble();  // 随机生成实时负荷
        //模拟来煤、耗煤、存煤数量
        double minCoal = 123456;  // 最小
        double maxCoal = 987654;  // 最大
        double inCoal = minCoal + (maxCoal - minCoal) * random.nextDouble();
        double useCoal = minCoal + (maxCoal - minCoal) * random.nextDouble();
        double stockCoal = minCoal + (maxCoal - minCoal) * random.nextDouble();
        //模拟当日负荷和计划过程，实际负荷过程模拟到当前小时
        //模拟负荷过程采用96点计划
        List<GenericKeyValuePairDto<Date, Double>> plantodaymws = new ArrayList<>();
        List<GenericKeyValuePairDto<Date, Double>> todaymws = new ArrayList<>();

        Date beginTime = DateUtil.getDayDate(date);
        Date endTime = DateUtil.addDays(beginTime, 1);
        while (beginTime.after(endTime) == false) {
            double plan = 450.0d;// minDynamoMw + (maxDynamoMw - minDynamoMw) * random.nextDouble();
            double mw = 420 + 50 * random.nextDouble();

            GenericKeyValuePairDto<Date, Double> kv = new GenericKeyValuePairDto<>();
            kv.setKey(beginTime);
            kv.setValue(plan);
            //模拟没有发电计划，赋值为NaN
            //kv.setValue(NaN);
            plantodaymws.add(kv);

            //如果时间小时数小于当前时间的小时数，对实际负荷过程进行赋值
            if (DateUtil.getHour(beginTime) <= DateUtil.getHour(DateUtil.getNowDate())) {
                kv = new GenericKeyValuePairDto<>();
                kv.setKey(beginTime);
                kv.setValue(mw);
                todaymws.add(kv);
            }

            beginTime = DateUtil.addMinutes(beginTime, 15);
        }

        //3机组数据
        dynamoData1.setName("#3机组");
        dynamoData1.setCapacity(300.0f);
        dynamoData1.setMw(mw1);
        dynamoData1.setSo2(monthEngc1);
        dynamoData1.setNox(todayEngc1);
        dynamoData1.setSmoke(yesterdayEngc1);

        //4机组数据
        dynamoData2.setName("#4机组");
        dynamoData2.setCapacity(300.0f);
        dynamoData2.setMw(mw2);
        dynamoData2.setSo2(monthEngc2);
        dynamoData2.setNox(todayEngc2);
        dynamoData2.setSmoke(yesterdayEngc2);

        //添加到结果集
        reservoirData.setName("国能阳宗海发电有限公司");
        reservoirData.setCapacity(dynamoData1.getCapacity() + dynamoData2.getCapacity());//装机总容量，单位：MW
        reservoirData.setMw(dynamoData1.getMw() + dynamoData2.getMw());//总负荷，单位：MW
        reservoirData.setEngcyestoday(yesterdayEngc1 + yesterdayEngc2);//昨日电量
        reservoirData.setEngctoday(todayEngc1 + todayEngc2);//今日电量
        reservoirData.setPlanengctoday(todayPlanEngc1 + todayPlanEngc2);//今日计划电量
        reservoirData.setEngcmonth(monthEngc1 + monthEngc2);//本月电量
        reservoirData.setPlanengcmonth(monthPlanEngc1 + monthPlanEngc2);//本月计划电量
        reservoirData.setEngcyear(yearEngc1 + yearEngc2);//本年电量
        reservoirData.setPlanengcyear(yearPlanEngc1 + yearPlanEngc2);//本年计划电量
        //reservoirData.setIncoal(inCoal);
        //reservoirData.setUsecoal(useCoal);
        //reservoirData.setStockcoal(stockCoal);
        //reservoirData.setIncoal(10760.98f);
        //reservoirData.setUsecoal(257932.85f);
        //reservoirData.setStockcoal(6500.83f);
        //模拟煤数据值为NaN
        reservoirData.setIncoal(NaN);
        reservoirData.setUsecoal(NaN);
        reservoirData.setStockcoal(NaN);
        reservoirData.setTodaymws(todaymws);
        reservoirData.setPlantodaymws(plantodaymws);

        dynamoDatas.add(dynamoData1);
        dynamoDatas.add(dynamoData2);

        result.setReservoir(reservoirData);
        result.setDynamos(dynamoDatas);

        return result;
    }
}
